001 /* 002 * Copyright 2005-2006 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.metro.info; 020 021 import java.io.Serializable; 022 023 import net.dpml.lang.Version; 024 025 /** 026 * This ServiceDescriptor defines the interface and service version 027 * published by a service instance. 028 * 029 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 030 * @version 1.0.1 031 */ 032 public final class ServiceDescriptor implements Serializable 033 { 034 /** 035 * Serial version identifier. 036 */ 037 static final long serialVersionUID = 1L; 038 039 /** 040 * The name of service class. 041 */ 042 private final String m_classname; 043 044 /** 045 * The version of service class. 046 */ 047 private final Version m_version; 048 049 /** 050 * Construct a service with specified type. The type argument will be 051 * parsed for a classname and version in the form [classname]#[version]. 052 * If not version is present a default 1.0.0 version will be assigned. 053 * 054 * @param spec the service specification 055 * @exception NullPointerException if the spec is null 056 */ 057 public ServiceDescriptor( final String spec ) throws NullPointerException 058 { 059 this( parseClassname( spec ), parseVersion( spec ) ); 060 } 061 062 /** 063 * Construct a service with specified name, version. 064 * 065 * @param classname the name of the service 066 * @param version the version of service 067 * @exception NullPointerException if the classname or version is null 068 */ 069 public ServiceDescriptor( final String classname, final Version version ) 070 throws NullPointerException 071 { 072 if( null == classname ) 073 { 074 throw new NullPointerException( "classname" ); 075 } 076 if( classname.equals( "" ) ) 077 { 078 throw new NullPointerException( "classname" ); 079 } 080 081 m_classname = classname; 082 083 if( null == version ) 084 { 085 m_version = Version.parse( "1" ); 086 } 087 else 088 { 089 m_version = version; 090 } 091 } 092 093 /** 094 * Return classname of service specification. 095 * 096 * @return the classname of the service specification 097 */ 098 public String getClassname() 099 { 100 return m_classname; 101 } 102 103 /** 104 * Return the service version. 105 * 106 * @return the version of interface 107 */ 108 public Version getVersion() 109 { 110 return m_version; 111 } 112 113 /** 114 * Determine if specified service will match this service. 115 * To match a service has to have same name and must comply with version. 116 * 117 * @param other the other ServiceInfo 118 * @return true if matches, false otherwise 119 */ 120 public boolean matches( final ServiceDescriptor other ) 121 { 122 if( !m_classname.equals( other.m_classname ) ) 123 { 124 return false; 125 } 126 else 127 { 128 return other.getVersion().complies( getVersion() ); 129 } 130 } 131 132 /** 133 * Convert to a string of format name:version 134 * 135 * @return string describing service 136 */ 137 public String toString() 138 { 139 return getClassname() + ":" + getVersion(); 140 } 141 142 /** 143 * Compare this object with another for equality. 144 * @param other the object to compare this object with 145 * @return TRUE if the supplied object is a reference, service, or service 146 * descriptor that matches this objct in terms of classname and version 147 */ 148 public boolean equals( Object other ) 149 { 150 if( !( other instanceof ServiceDescriptor ) ) 151 { 152 return false; 153 } 154 155 ServiceDescriptor service = (ServiceDescriptor) other; 156 if( !getClassname().equals( service.getClassname() ) ) 157 { 158 return false; 159 } 160 else 161 { 162 return getVersion().equals( service.getVersion() ); 163 } 164 } 165 166 /** 167 * Returns the cashcode. 168 * @return the hascode value 169 */ 170 public int hashCode() 171 { 172 return getClassname().hashCode() ^ getVersion().hashCode(); 173 } 174 175 private static final String parseClassname( final String spec ) 176 throws NullPointerException 177 { 178 if( spec == null ) 179 { 180 throw new NullPointerException( "spec" ); 181 } 182 183 int index = spec.indexOf( "#" ); 184 if( index == -1 ) 185 { 186 return spec; 187 } 188 else 189 { 190 return spec.substring( 0, index ); 191 } 192 } 193 194 private static final Version parseVersion( final String spec ) 195 { 196 int index = spec.indexOf( "#" ); 197 if( index == -1 ) 198 { 199 return Version.parse( "1" ); 200 } 201 else 202 { 203 String value = spec.substring( index + 1 ); 204 return Version.parse( value ); 205 } 206 } 207 }